/**
 * DiggApiNet - Digg API .NET Wrapper
 * 
 * Author: Sean Hickey
 * Link: http://www.headzoo.com/digg_api_net
 * License: GPL v2 ( http://www.gnu.org/licenses/gpl.txt )
 * Version: 0.2
 * Date: May, 2007
 */
using System;
using System.Collections;
using System.Text;
using System.Xml;
using System.Net;
using System.Web;

namespace DiggApiNet
{
    public partial class DiggApi
    {
        private static string _appkey;
        private static string _useragent;

        public static string AppKey
        {
            get
            {
                return _appkey;
            }
            set
            {
                _appkey = value;
            }
        }
        public static string UserAgent
        {
            get
            {
                return _useragent;
            }
            set
            {
                _useragent = value;
            }
        }

        public delegate void RequestPrepareHandler(object sender, DiggRequestArgs e);
        public event RequestPrepareHandler RequestPrepare;
        protected void OnRequestPrepare(DiggRequestArgs e)
        {
            if (RequestPrepare == null) {
                return;
            }
            RequestPrepare(this, e);
        }

        public delegate void RequestSuccessHandler(object sender, XmlDocument xml_doc);
        public event RequestSuccessHandler RequestSuccess;
        protected void OnRequestSuccess(XmlDocument xml_doc)
        {
            if (RequestSuccess == null) {
                return;
            }
            RequestSuccess(this, xml_doc);
        }

        /// <summary>
        /// Makes a request for a remote XML file through the Digg API.
        /// </summary>
        /// <param name="uri">The URI for the remote resource</param>
        /// <returns>XmlDocument of the returned XML</returns>
        public XmlDocument Request(string uri)
        {
            OnRequestPrepare(new DiggRequestArgs(uri));
            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(uri);
            if (String.IsNullOrEmpty(_useragent)) {
                _useragent = ".NET/2.0";
            }
            request.UserAgent = _useragent;
            XmlDocument xml_doc = new XmlDocument();
            try {
                xml_doc.Load(request.GetResponse().GetResponseStream());
            }
            #region Catch
            catch (WebException ex) {
                if (ex.Message.IndexOf("403") != -1) {
                    throw new DiggApiException(ex.Message, 403, ex);
                }
                if (ex.Message.IndexOf("404") != -1) {
                    throw new DiggApiException(ex.Message, 404, ex);
                }
                if (ex.Message.IndexOf("500") != -1) {
                    throw new DiggApiException(ex.Message, 500, ex);
                }
                throw ex;
            #endregion
            }

            OnRequestSuccess(xml_doc);
            return xml_doc;
        }

        /// <summary>
        /// Builds an HTTP query string using the key/value pairs in a HashTable
        /// </summary>
        /// <param name="args">The key/value pairs</param>
        /// <returns>An HTTP query string</returns>
        public static string HttpBuildUrl(Hashtable args)
        {
            StringBuilder query = new StringBuilder(HttpBuildAppKeyUrl(), 100);

            foreach (string key in args.Keys) {
                query.Append("&");
                query.Append(key);
                query.Append("=");
                Type arg_type = args[key].GetType();
                if (arg_type == typeof(int) || arg_type == typeof(Int32) || arg_type == typeof(Int64) || arg_type == typeof(long)) {
                    query.Append(args[key].ToString());
                }
                else if (arg_type == typeof(DateTime)) {
                    query.Append(GetUnixTimeStamp((DateTime)args[key]));
                }
                else {
                    query.Append(HttpUtility.UrlEncode((string)args[key]));
                }
            }

            return query.ToString();
        }

        /// <summary>
        /// Builds an HTTP query string for the set AppKey
        /// </summary>
        /// <returns>The HTTP query string</returns>
        public static string HttpBuildAppKeyUrl()
        {
            StringBuilder query = new StringBuilder("?appkey=", 100);
            query.Append(HttpUtility.UrlEncode(_appkey));
            return query.ToString();
        }

        /// <summary>
        /// Returns a Unix timestamp from a DateTime object
        /// </summary>
        /// <param name="date_time_convert">The DateTime object</param>
        /// <returns>A Unix timestamp</returns>
        public static long GetUnixTimeStamp(DateTime date_time_convert)
        {
            DateTime date_time_base = new DateTime(1970, 1, 1, 0, 0, 0, 0);
            TimeSpan span = date_time_convert.ToUniversalTime() - date_time_base;
            return (long)span.TotalSeconds;
        }

        /// <summary>
        /// Returns a DateTime object for the given Unix timestamp
        /// </summary>
        /// <param name="timestamp">The Unix timestamp</param>
        /// <returns>The DateTime object</returns>
        public static DateTime GetDateTimeFromTimeStamp(long timestamp)
        {
            DateTime date_time = new DateTime(1970, 1, 1, 0, 0, 0, 0);
            return date_time.AddSeconds(timestamp);
        }

        /// <summary>
        /// Returns a DateTime object for the given Unix timestamp
        /// </summary>
        /// <param name="timestamp">The Unix timestamp</param>
        /// <returns>The DateTime object</returns>
        public static DateTime GetDateTimeFromTimeStamp(string timestamp)
        {
            if (timestamp == null) {
                return new DateTime();
            }
            return GetDateTimeFromTimeStamp(long.Parse(timestamp));
        }
    }

    public struct DiggRequestArgs
    {
        public string RequestUri;

        public DiggRequestArgs(string request_uri)
        {
            RequestUri = request_uri;
        }
    }
}
